package com.xiaolee.hotool.json;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class MapTreeNode extends TreeNode {
    List<TreeNode> children;

    public MapTreeNode() {
        children = new ArrayList<>();
    }

    @Override
    TreeNode createNodeIfAbsent(PathIterator iterator, int index, Object value) {
        PathSegment segment = iterator.get();
        TreeNode child = child(segment.getName());

        TreeNode result = null;
        if (child != null) {
            if (segment.isArray()) {
                ((ListTreeNode) child).resizeIfNeed(segment.getArrayIndex());
            }

            // 最后一层
            if (!iterator.hasNext()) {
                ValueTreeNode target = new ValueTreeNode();
                target.setValue(value);

                if (segment.isArray()) {
                    target.setName(String.valueOf(segment.getArrayIndex()));
                    child.children().set(segment.getArrayIndex(), target);
                } else {
                    ((ValueTreeNode) child).setValue(value);
                }
            }

            result = child;
        } else {
            if (segment.isArray()) {
                ListTreeNode container = new ListTreeNode();
                container.setName(segment.getName());
                container.resizeIfNeed(segment.getArrayIndex());
                children.add(container);

                if (!iterator.hasNext()) {
                    ValueTreeNode target = new ValueTreeNode();
                    target.setValue(value);

                    target.setName(String.valueOf(segment.getArrayIndex()));
                    container.children().set(segment.getArrayIndex(), target);
                }

                result = container;
            } else {
                if (!iterator.hasNext()) {
                    ValueTreeNode target = new ValueTreeNode();
                    target.setValue(value);
                    target.setName(segment.getName());

                    children.add(target);
                } else {
                    MapTreeNode target = new MapTreeNode();
                    target.setName(segment.getName());
                    children.add(target);

                    result = target;
                }
            }

        }

        return result;
    }

    List<TreeNode> children() {
        return children;
    }

    TreeNode child(String name) {
        if (children.size() > 0) {
            for (TreeNode child : children) {
                if (name.equals(child.getName())) {
                    return child;
                }
            }
        }

        return null;
    }

    Object value() {
        JSONObject value = new JSONObject();
        if (children.size() > 0) {
            for (TreeNode child : children) {
                value.putOnce(child.getName(), child.value());
            }
        }

        return value;
    }
}
